﻿Imports System.Drawing
Imports System.Windows.Forms

Namespace Forms.Utilities
    Public Class ControlBoxManager
        Implements IDisposable

        Private disposedValue As Boolean = False        ' 检测冗余的调用

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: 释放其他状态(托管对象)。
                End If

                ' TODO: 释放您自己的状态(非托管对象)。
                ' TODO: 将大型字段设置为 null。
                Me.m_Form = Nothing
            End If
            Me.disposedValue = True
        End Sub

#Region " IDisposable Support "
        ' Visual Basic 添加此代码是为了正确实现可处置模式。
        Public Sub Dispose() Implements IDisposable.Dispose
            ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean) 中。
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

#Region "Variables"
        Private m_Form As FormBase = Nothing
        Private m_IsMouseDown As Boolean = False
        Private m_CloseBoxState As ControlBoxState = ControlBoxState.Normal
        Private m_MinimizeBoxState As ControlBoxState = ControlBoxState.Normal
        Private m_MaximizeBoxState As ControlBoxState = ControlBoxState.Normal
#End Region

#Region "Properties"

        Public ReadOnly Property CloseBoxVisible() As Boolean
            Get
                Return Me.m_Form.ControlBox
            End Get
        End Property

        Public ReadOnly Property MaximizeBoxVisibale() As Boolean
            Get
                Return Me.m_Form.ControlBox And Me.m_Form.MaximizeBox
            End Get
        End Property

        Public ReadOnly Property MinimizeBoxVisibale() As Boolean
            Get
                Return Me.m_Form.ControlBox And Me.m_Form.MinimizeBox
            End Get
        End Property

        Public ReadOnly Property CloseBoxRect() As Rectangle
            Get
                If (Me.CloseBoxVisible) Then
                    Dim _Size As Size = Me.m_Form.CloseBoxSize
                    Return New Rectangle(Me.m_Form.Width - _Size.Width - Me.m_Form.Padding.Right, _
                                         0, _Size.Width, _Size.Height)
                End If
                Return Rectangle.Empty
            End Get
        End Property

        Public ReadOnly Property MaximizeBoxRect() As Rectangle
            Get
                If (Me.MaximizeBoxVisibale) Then
                    Dim _Size As Size = Me.m_Form.MaximizeBoxSize
                    Return New Rectangle(Me.CloseBoxRect.X - _Size.Width, _
                                         0, _Size.Width, _Size.Height)
                End If
                Return Rectangle.Empty
            End Get
        End Property

        Public ReadOnly Property MinimizeBoxRect() As Rectangle
            Get
                If (Me.MinimizeBoxVisibale) Then
                    Dim _Size As Size = Me.m_Form.MinimizeBoxSize
                    Dim _X As Integer = 0
                    If Me.MaximizeBoxVisibale Then
                        _X = Me.MaximizeBoxRect.X - _Size.Width
                    Else
                        _X = Me.CloseBoxRect.X - _Size.Width
                    End If
                    Return New Rectangle(_X, 0, _Size.Width, _Size.Height)
                End If
                Return Rectangle.Empty
            End Get
        End Property

        Public Property CloseBoxState() As ControlBoxState
            Get
                Return Me.m_CloseBoxState
            End Get
            Protected Set(ByVal value As ControlBoxState)
                If Me.m_CloseBoxState <> value Then
                    Me.m_CloseBoxState = value
                    Invalidate(Me.CloseBoxRect)
                End If
            End Set
        End Property

        Public Property MaximizeBoxState() As ControlBoxState
            Get
                Return Me.m_MaximizeBoxState
            End Get
            Protected Set(ByVal value As ControlBoxState)
                If Me.m_MaximizeBoxState <> value Then
                    Me.m_MaximizeBoxState = value
                    Invalidate(Me.MaximizeBoxRect)
                End If
            End Set
        End Property

        Public Property MinimizeBoxState() As ControlBoxState
            Get
                Return Me.m_MinimizeBoxState
            End Get
            Protected Set(ByVal value As ControlBoxState)
                If Me.m_MinimizeBoxState <> value Then
                    Me.m_MinimizeBoxState = value
                    Invalidate(Me.MinimizeBoxRect)
                End If
            End Set
        End Property

#End Region

#Region "Constructor"
        Public Sub New(ByVal frm As FormBase)
            Me.m_Form = frm
        End Sub
#End Region

#Region "Methods"
        '[Private]－－－－－－－－－－－－－－－－－－－－－－－
        Private Sub Invalidate(ByVal rect As Rectangle)
            If Me.m_Form IsNot Nothing Then
                Me.m_Form.Invalidate(rect)
            End If
        End Sub

        Private Sub processMouseMove(ByVal mousePoint As Point, _
                                     ByVal closeBoxRect As Rectangle, _
                                     ByVal minimizeBoxRect As Rectangle, _
                                     ByVal maximizeBoxRect As Rectangle, _
                                     ByVal closeBoxVisibale As Boolean, _
                                     ByVal minimizeBoxVisibale As Boolean, _
                                     ByVal maximizeBoxVisibale As Boolean)
            Dim _Hide As Boolean = True
            If closeBoxVisibale Then
                If Me.CloseBoxRect.Contains(mousePoint) Then
                    _Hide = False
                    If Me.m_IsMouseDown = False Then
                        'if (CloseBoxState != ControlBoxState.Hover)
                        '{
                        '    toolTip = "关闭";
                        '}
                        Me.CloseBoxState = ControlBoxState.Hover
                    Else
                        If Me.CloseBoxState = ControlBoxState.PressedLeave Then
                            Me.CloseBoxState = ControlBoxState.Pressed
                        End If
                    End If
                Else
                    If Me.m_IsMouseDown = False Then
                        Me.CloseBoxState = ControlBoxState.Normal
                    Else
                        If Me.CloseBoxState = ControlBoxState.Pressed Then
                            Me.CloseBoxState = ControlBoxState.PressedLeave
                        End If
                    End If
                End If
            End If

            If minimizeBoxVisibale Then
                If minimizeBoxRect.Contains(mousePoint) Then
                    _Hide = False
                    If Me.m_IsMouseDown = False Then
                        'if (MinimizeBoxState != ControlBoxState.Hover)
                        '{
                        '    toolTip = "最小化";
                        '}
                        Me.MinimizeBoxState = ControlBoxState.Hover
                    Else
                        If Me.MinimizeBoxState = ControlBoxState.PressedLeave Then
                            Me.MinimizeBoxState = ControlBoxState.Pressed
                        End If
                    End If
                Else
                    If Me.m_IsMouseDown = False Then
                        Me.MinimizeBoxState = ControlBoxState.Normal
                    Else
                        If Me.MinimizeBoxState = ControlBoxState.Pressed Then
                            Me.MinimizeBoxState = ControlBoxState.PressedLeave
                        End If
                    End If
                End If
            End If

            If maximizeBoxVisibale Then
                If maximizeBoxRect.Contains(mousePoint) Then
                    _Hide = False
                    If Me.m_IsMouseDown = False Then
                        'if (MaximizeBoxState != ControlBoxState.Hover)
                        '{
                        '    bool maximize = 
                        '        _owner.WindowState == FormWindowState.Maximized;
                        '    toolTip = maximize ? "还原" : "最大化";
                        '}
                        Me.MaximizeBoxState = ControlBoxState.Hover
                    Else
                        If Me.MaximizeBoxState = ControlBoxState.PressedLeave Then
                            Me.MaximizeBoxState = ControlBoxState.Pressed
                        End If
                    End If
                Else
                    If Me.m_IsMouseDown = False Then
                        Me.MaximizeBoxState = ControlBoxState.Normal
                    Else
                        If Me.MaximizeBoxState = ControlBoxState.Pressed Then
                            Me.MaximizeBoxState = ControlBoxState.PressedLeave
                        End If
                    End If
                End If
            End If

            'if (toolTip != string.Empty)
            '{
            '    HideToolTip();
            '    ShowTooTip(toolTip);
            '}

            '    If (hide) Then
            '{
            '    HideToolTip();
            '}
        End Sub

        Private Sub ProcessMouseDown(ByVal mousePoint As Point, _
                                     ByVal closeBoxRect As Rectangle, _
                                     ByVal minimizeBoxRect As Rectangle, _
                                     ByVal maximizeBoxRect As Rectangle, _
                                     ByVal closeBoxVisibale As Boolean, _
                                     ByVal minimizeBoxVisibale As Boolean, _
                                     ByVal maximizeBoxVisibale As Boolean)
            Me.m_IsMouseDown = True

            If closeBoxVisibale Then
                If closeBoxRect.Contains(mousePoint) Then
                    Me.CloseBoxState = ControlBoxState.Pressed
                    Exit Sub
                End If
            End If

            If minimizeBoxVisibale Then
                If minimizeBoxRect.Contains(mousePoint) Then
                    Me.MinimizeBoxState = ControlBoxState.Pressed
                    Exit Sub
                End If
            End If

            If maximizeBoxVisibale Then
                If maximizeBoxRect.Contains(mousePoint) Then
                    Me.MaximizeBoxState = ControlBoxState.Pressed
                    Exit Sub
                End If
            End If
        End Sub

        Private Sub processMouseUp(ByVal mousePoint As Point, _
                                   ByVal closeBoxRect As Rectangle, _
                                   ByVal minimizeBoxRect As Rectangle, _
                                   ByVal maximizeBoxRect As Rectangle, _
                                   ByVal closeBoxVisibale As Boolean, _
                                   ByVal minimizeBoxVisibale As Boolean, _
                                   ByVal maximizeBoxVisibale As Boolean)
            Me.m_IsMouseDown = False

            If closeBoxVisibale Then
                If closeBoxRect.Contains(mousePoint) Then
                    If Me.CloseBoxState = ControlBoxState.Pressed Then
                        Me.CloseBoxState = ControlBoxState.Normal
                        Me.m_Form.Close()
                        Exit Sub
                    End If
                End If
                Me.CloseBoxState = ControlBoxState.Normal
            End If

            If minimizeBoxVisibale Then
                If minimizeBoxRect.Contains(mousePoint) Then
                    If Me.MinimizeBoxState = ControlBoxState.Pressed Then
                        Me.m_Form.WindowState = FormWindowState.Minimized
                        Me.MinimizeBoxState = ControlBoxState.Normal
                        Exit Sub
                    End If
                End If
                Me.MinimizeBoxState = ControlBoxState.Normal
            End If

            If maximizeBoxVisibale Then
                If maximizeBoxRect.Contains(mousePoint) Then
                    If Me.MaximizeBoxState = ControlBoxState.Pressed Then
                        Dim _Maximize As Boolean = (Me.m_Form.WindowState = FormWindowState.Maximized)
                        If _Maximize Then
                            Me.m_Form.WindowState = FormWindowState.Normal
                        Else
                            Me.m_Form.WindowState = FormWindowState.Maximized
                        End If
                        Me.MaximizeBoxState = ControlBoxState.Normal
                        Exit Sub
                    End If
                End If
                Me.MaximizeBoxState = ControlBoxState.Normal
            End If
        End Sub

        Private Sub processMouseLeave(ByVal closeBoxVisiable As Boolean, _
                                      ByVal minimizeBoxVisibale As Boolean, _
                                      ByVal maximizeBoxVisibale As Boolean)

            If closeBoxVisiable Then
                If Me.CloseBoxState = ControlBoxState.Pressed Then
                    Me.CloseBoxState = ControlBoxState.PressedLeave
                Else
                    Me.CloseBoxState = ControlBoxState.Normal
                End If
            End If

            If minimizeBoxVisibale Then
                If Me.MinimizeBoxState = ControlBoxState.Pressed Then
                    Me.MinimizeBoxState = ControlBoxState.PressedLeave
                Else
                    Me.MinimizeBoxState = ControlBoxState.Normal
                End If
            End If

            If maximizeBoxVisibale Then
                If Me.MaximizeBoxState = ControlBoxState.Pressed Then
                    Me.MaximizeBoxState = ControlBoxState.PressedLeave
                Else
                    Me.MaximizeBoxState = ControlBoxState.Normal
                End If
            End If

            'HideToolTip();
        End Sub


        '[Protected]－－－－－－－－－－－－－－－－－－－－－－－


        '[Public]－－－－－－－－－－－－－－－－－－－－－－－
        Public Sub ProcessMouseOperate(ByVal mousePoint As Point, ByVal operate As MouseOperate)
            If Me.m_Form.ControlBox = False Then
                Exit Sub
            End If

            Dim _CloseBoxRect As Rectangle = Me.CloseBoxRect
            Dim _MaximizeBoxRect As Rectangle = Me.MaximizeBoxRect
            Dim _MinimizeBoxRect As Rectangle = Me.MinimizeBoxRect

            Dim _CloseBoxVisible As Boolean = Me.CloseBoxVisible
            Dim _MaximizeBoxVisible As Boolean = Me.MaximizeBoxVisibale
            Dim _MinimizeBoxVisible As Boolean = Me.MinimizeBoxVisibale

            Select Case operate
                Case MouseOperate.Move
                    Me.processMouseMove(mousePoint, _CloseBoxRect, _MinimizeBoxRect, _MaximizeBoxRect, _CloseBoxVisible, _MinimizeBoxVisible, _MaximizeBoxVisible)
                    Exit Select
                Case MouseOperate.Down
                    Me.ProcessMouseDown(mousePoint, _CloseBoxRect, _MinimizeBoxRect, _MaximizeBoxRect, _CloseBoxVisible, _MinimizeBoxVisible, _MaximizeBoxVisible)
                    Exit Select
                Case MouseOperate.Up
                    Me.processMouseUp(mousePoint, _CloseBoxRect, _MinimizeBoxRect, _MaximizeBoxRect, _CloseBoxVisible, _MinimizeBoxVisible, _MaximizeBoxVisible)
                    Exit Select
                Case MouseOperate.Leave
                    Me.processMouseLeave(_CloseBoxVisible, _MinimizeBoxVisible, _MaximizeBoxVisible)
                    Exit Select
                Case Else
                    Exit Select
            End Select
        End Sub

#End Region


    End Class
End Namespace

